﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sealight.API.Framework;
using Sealight.Data;
using Sealight.API.Ioc;
using Sealight.Core.Domain;
using Sealight.Core.DataAdapter;
using Sealight.Core.Common;

namespace Sealight.CoreAPI
{
  public  class TopicService: ITopicService
    {

        #region ITopicService Members

        public topic AddOrUpdate(topic data)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();

                TopicEntity entity = repo.GetById(data.id);

                if (entity == null)
                    entity = new TopicEntity();

                entity.Name = data.name;

                if (data.topic_localized != null)
                {                   
                    entity.TopicLocalized = new List<TopicLocalizedEntity>();

                    foreach (topic_localized topic_local in data.topic_localized)
                    {
                        TopicLocalizedEntity topicLocalized = new Core.Domain.TopicLocalizedEntity();

                        topicLocalized.Title = topic_local.title;
                        topicLocalized.Description = topic_local.description;
                        topicLocalized.Body = topic_local.body;
                        topicLocalized.CreatedDate = topic_local.created_date;
                        topicLocalized.UpdatedDate = topic_local.updated_date;

                        if(topic_local.language != null)
                        topicLocalized.Language = repo.GetLanguageById(topic_local.language.id);

                        topicLocalized.Topic = entity;

                        entity.TopicLocalized.Add(topicLocalized);
                    }
                }

                repo.SaveOrUpdate(entity);

                if (commitTrans)
                    uow.TransactionalFlush();

                data = entity.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving topic data. ErrMsg: " + ex.Message, ex);
            }

            return data;
        }

        public topic_localized SaveOrUpdateTopicLocalized(topic_localized data)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();

                TopicLocalizedEntity entity = repo.GetTopicLocalizedById(data.id);

                if (entity == null)
                    entity = new TopicLocalizedEntity();

                entity.Title = data.title;
                entity.Description = data.description;
                entity.Body = data.body;
                entity.CreatedDate = data.created_date;
                entity.UpdatedDate = data.updated_date;

                if (data.language != null)
                    entity.Language = repo.GetLanguageById(data.language.id);

                if (data.topic != null)
                    entity.Topic = repo.GetById(data.topic.id);

                repo.SaveOrUpdateTopicLocalized(entity);

                if (commitTrans)
                    uow.TransactionalFlush();

                data = entity.ToDataAdapter();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving TopicLocalized data. ErrMsg: " + ex.Message, ex);
            }

            return data;
        }

        public topic GetById(Guid id)
        {
            if (id == Guid.Empty)
                throw new ArgumentNullException("Topic ID cannot be NULL.");

            TopicEntity data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                data = repo.GetById(id);
            }
            catch (Exception ex)
            {
                throw new Exception("Get Content Error::" + ex.Message, ex);
            }

            if (data != null)
                return data.ToDataAdapter();

            return null;
        }

        public topic_localized GetTopicLocalizedById(Guid id)
        {
            if (id == Guid.Empty)
                throw new ArgumentNullException("TopicLocalizedEntity ID cannot be NULL.");

            TopicLocalizedEntity data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                data = repo.GetTopicLocalizedById(id);
            }
            catch (Exception ex)
            {
                throw new Exception("Get TopicLocalizedEntity Error::" + ex.Message, ex);
            }

            if (data != null)
                return data.ToDataAdapter();

            return null;
        }

        public topic_localized GetTopicLocalized(Guid topicId, Guid languageId)
        {

            if (topicId == Guid.Empty)
                throw new ArgumentNullException("topic ID cannot be NULL.");

            TopicLocalizedEntity data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                data = repo.GetTopicLocalized(topicId, languageId);
            }
            catch (Exception ex)
            {
                throw new Exception("Get GetTopicLocalized Error::" + ex.Message, ex);
            }

            if (data != null)
                return data.ToDataAdapter();

            return null;
        }

        public void Delete(topic data)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                TopicEntity entity = repo.GetById(data.id);
                repo.Delete(entity);

                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving user data. ErrMsg: " + ex.Message, ex);
            }
        }

        public IList<topic> GetAll()
        {
            IList<TopicEntity> listData = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                listData = repo.GetAll();
            }
            catch (Exception ex)
            {
                throw new Exception("Error get topic data. ErrMsg: " + ex.Message, ex);
            }
            IList<topic> dataAdapter = null;
            if (listData != null)
            {
                dataAdapter = new List<topic>();
                foreach (TopicEntity entity in listData)
                {
                    dataAdapter.Add(entity.ToDataAdapter());
                }
            }
            return dataAdapter;
        }       

        public language GetLanguageById(Guid id)
        {
            if (id == Guid.Empty)
                throw new ArgumentNullException("Language ID cannot be NULL.");

            LanguageEntity data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                data = repo.GetLanguageById(id);
            }
            catch (Exception ex)
            {
                throw new Exception("Get Language Data Error::" + ex.Message, ex);
            }

            if (data != null)
                return data.ToDataAdapter();

            return null;
        }

        public picture GetPictureById(Guid id)
        {
            if (id == Guid.Empty)
                throw new ArgumentNullException("News ID cannot be NULL.");

            PictureEntity data = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                data = repo.GetPictureById(id);
            }
            catch (Exception ex)
            {
                throw new Exception("Get Service Error::" + ex.Message, ex);
            }

            if (data != null)
                return data.ToDataAdapter();

            return null;
        }

        public picture SaveOrUpdatePicture(picture data)
        {
            if (data == null)
                throw new ArgumentNullException("News data is Null.");
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }
            try
            {
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                PictureEntity entity = repo.GetPictureById(data.id);

                if (entity == null)
                    entity = new PictureEntity();
                entity.Name = data.name;
                entity.Extension = data.extension;
                entity.Order = data.order;
                entity.PictureURL = data.picture_url;


                repo.SaveOrUpdatePicture(entity);

                if (commitTrans)
                    uow.TransactionalFlush();

                data = entity.ToDataAdapter();
            }
            catch (Exception ex)
            {
            }

            return data;
        }
        public IList<picture> GetPicture()
        {
            IList<PictureEntity> listData = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                listData = repo.GetPicture();
            }
            catch (Exception ex)
            {
                throw new Exception("Error get service data. ErrMsg: " + ex.Message, ex);
            }
            IList<picture> dataAdapter = null;
            if (listData != null)
            {
                dataAdapter = new List<picture>();
                foreach (PictureEntity entity in listData)
                {
                    dataAdapter.Add(entity.ToDataAdapter());
                }
            }
            return dataAdapter.OrderBy(x => x.name).ToList();
        }

        public void DeletePicture(picture data)
        {
            //persists
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            try
            {
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                PictureEntity entity = repo.GetPictureById(data.id);

                repo.DeletePicture(entity);

                if (commitTrans)
                    uow.TransactionalFlush();
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error saving user data. ErrMsg: " + ex.Message, ex);
            }
        }

        public IList<menu> GetListMenu(MenuSource source, Guid languageId)
        {
            IList<MenuEntity> listData = null;
            try
            {
                #region start_unit_of_work
                IUnitOfWork uow = null;
                if (!UnitOfWork.IsStarted)
                    uow = UnitOfWork.Start();
                else uow = UnitOfWork.Current;
                #endregion
                ITopicDataRepository repo = IocContainer.Container().Resolve<ITopicDataRepository>();
                listData = repo.GetListMenu(source, languageId);
                IList<menu> dataAdapter = null;
                if (listData != null)
                {
                    dataAdapter = new List<menu>();
                    foreach (MenuEntity entity in listData)
                    {
                        dataAdapter.Add(entity.ToDataAdapter());
                    }
                }
                return dataAdapter.OrderBy(x => x.order).ToList();
                
            }
            catch (Exception ex)
            {
                //log for net
                throw new Exception("Error GetListMenu. ErrMsg: " + ex.Message, ex);
            }
        }

        #endregion
    }
}
